package dd.lo.ml;

import dd.lo.HelloCV;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.HOGDescriptor;

public class FeatureExtraction {

    public static final int IMG_STD_LEN = 128;

    private static final String ROOT = HelloCV.class.getResource("/").getPath();

    private static final HOGDescriptor hogDescriptor;

    static {
        System.load(ROOT + "libopencv_java481.dylib");

        //定义HOGDescriptor，参考文章，https://medium.com/@dnemutlu/hog-feature-descriptor-263313c3b40d
        Size winSize = new Size(IMG_STD_LEN, IMG_STD_LEN);
        Size cellSize = new Size(8, 8);
        Size blockSize = new Size(16, 16);
        Size blockStride = new Size(8, 8);
        hogDescriptor = new HOGDescriptor(winSize, blockSize, blockStride, cellSize, 9);
    }

    //计算结果的长度，由block数量，每个block的cell数量，nbins（9），相乘所得，例如128*128图像，cell8*8，block16*16，block_stride8*8，nbins=9，所得结果长度是8100
    public static MatOfFloat computeGrayImgHogFeature(Mat grayImg) {
        if (null == grayImg || grayImg.empty()) {
            throw new RuntimeException("灰度图不能为空");
        }
        if (grayImg.channels() > 1) {
            throw new RuntimeException("灰度图的通道数量应为1");
        }
        //图片统一大小512*512
        Imgproc.resize(grayImg, grayImg, new Size(IMG_STD_LEN, IMG_STD_LEN));
        //计算图片特征
        MatOfFloat imgFeature = new MatOfFloat();
        hogDescriptor.compute(grayImg, imgFeature);
        return imgFeature;
    }

    public static void main(String[] args) {
        //按灰度读取图片
//        Mat grayImg = Imgcodecs.imread("/Users/kwok/Downloads/train/western/12332_33_img_0.jpeg", Imgcodecs.IMREAD_GRAYSCALE);
        Mat grayImg = Imgcodecs.imread("/Users/kwok/Downloads/train/photo/Fri Jan 26 18:20:19 CST 2024_7_img_5.jpeg", Imgcodecs.IMREAD_GRAYSCALE);
        //图片统一大小512*512
        Imgproc.resize(grayImg, grayImg, new Size(IMG_STD_LEN, IMG_STD_LEN));
        //计算图片特征
        MatOfFloat imgFeature = new MatOfFloat();
        hogDescriptor.compute(grayImg, imgFeature);
        System.out.println(imgFeature.toList().toString());
    }
}
